/*************************************************
  * 描述：
  *
  * File：hotkey_p.cpp
  * Author：chenyujin@mozihealthcare.cn
  * Date：2025/9/12
  * Update：
  * ************************************************/
#include "hotkey_p.h"
#include <common/logger/logger.h>
#include <common/stringutil/stringutil.h>
#include <private/hotkey/keymapwin.h>

int HotKeyPrivate::registerHotKey(const QWidget* widget, const std::string& hotKey)
{
	if (hotKey.empty())
	{
		LOG_WARN("快捷键按键为空");
		return -1;
	}
	std::string hotKeyStr = StringUtil::upper(hotKey);// 转换为大写
#ifdef Q_OS_WIN
	HWND hwnd = nullptr;

	/*
	 * 这里逻辑分开：
	 * 如果窗口入参为空指针，说明需要全局注册
	 * 如果不为空，说明需要注册到窗口，需要拿到句柄，但如果句柄拿不到，注册失败
	 */
	if (widget)
	{
		if (widget->windowHandle())// 检查窗口存在时，句柄是否可以拿到
		{
			hwnd = reinterpret_cast<HWND>(widget->winId());
		}
		else
		{
			LOG_ERROR("热键注销：窗体存在，但是句柄没有准备好");
			return -1;
		}
	}

	return HotKeyPrivate::registerWin(hwnd, hotKeyStr);

#elif defined(Q_OS_UNIX)
	Window x11Win = 0；//0表示没有有效窗口

			if (widget)
	{
		if (widget->windowHandle())// 检查窗口存在时，句柄是否可以拿到
		{
			x11Win = widget->winId();
		}
		else
		{
			LOG_ERROR("热键注册：窗体存在，但是句柄没有准备好");
			return -1;
		}
	}


#endif
}
bool HotKeyPrivate::unregisterHotKey(QWidget* widget, int id)
{
#ifdef Q_OS_WIN
	HWND hwnd = nullptr;
	/*
	 * 这里逻辑分开：
	 * 如果窗口入参为空指针，说明需要全局注册
	 * 如果不为空，说明需要注册到窗口，需要拿到句柄，但如果句柄拿不到，注册失败
	 */
	if (widget)
	{
		if (widget->windowHandle())// 检查窗口存在时，句柄是否可以拿到
		{
			hwnd = reinterpret_cast<HWND>(widget->winId());
		}
		else
		{
			LOG_ERROR("热键注销：窗体存在，但是句柄没有准备好");
			return false;
		}
	}

	return HotKeyPrivate::unregisterWin(hwnd, id);
#elif defined(Q_OS_UNIX)
	return true;
#endif
}
int HotKeyPrivate::registerWin(HWND hwnd, const std::string& hotKeyStr)
{
	UINT modifiers = 0;
	UINT vk_key = 0;

	// 获取热键对应快捷键按键码
	{
		const std::vector<std::string> keys = StringUtil::splitStr(hotKeyStr, '+');
		if (keys.empty())
		{
			LOG_ERROR("快捷键按键列表为空");
			return -1;
		}

		for (const auto& key: keys)
		{
			if (keyMapWin::modMap.find(key) != keyMapWin::modMap.end())
			{
				modifiers += keyMapWin::modMap[key];
				continue;
			}
			if (keyMapWin::keyMap.find(key) != keyMapWin::keyMap.end())
			{
				vk_key = keyMapWin::keyMap[key];
				break;
			}
		}
		if (vk_key == 0)
		{
			LOG_ERROR("没有找到对应键盘按键");
			return -1;
		}
	}

	// 创建热键id
	const uint16_t id = GlobalAddAtomA(hotKeyStr.c_str());// 根据快捷键按键获取Windows全局原子值，确保id的唯一性和原子性

	// 注册快捷键
	if (!RegisterHotKey(hwnd, id, modifiers, vk_key))// 第二个参数为快捷键id，自由定义
	{
		LOG_WARN("Windows快捷键添加失败");
		if (GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED)
		{
			LOG_WARN("该快捷键已被注册");
		}
		return -1;
	}
	LOG_INFO("Windows快捷键添加成功: id: ", static_cast<int>(id), ", 快捷键: ", hotKeyStr);
	return id;
}
bool HotKeyPrivate::unregisterWin(HWND hwnd, int id)
{
	return UnregisterHotKey(hwnd, id);
}